﻿using log4net.Appender;
using log4net.Core;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Windows.Forms;

namespace HobSoft.SoccerBet2014.Server.Log
{
    public class ApplicationCacheLogAppender : AppenderSkeleton
    {
        public ApplicationCacheLogAppender()
        {
            bindCacheList = new List<LogCacheCollection>();
        }

        private IList<LogCacheCollection> bindCacheList;
        protected override void Append(LoggingEvent loggingEvent)
        {
            foreach (var cacheList in bindCacheList)
            {
                while (cacheList.Collection.Count > cacheList.MaxQueueCount)
                {
                    lock (cacheList.SyncRoot)
                    {
                        if (cacheList.Collection.Count > cacheList.MaxQueueCount)
                        {
                            var last = cacheList.Collection.LastOrDefault();
                            if (last != null)
                            {
                                if (cacheList.CollectionOwner.InvokeRequired)
                                {
                                    cacheList.CollectionOwner.Invoke(new System.Threading.ThreadStart(delegate()
                                    {
                                        cacheList.Collection.Remove(last);
                                    }));
                                }
                                else
                                {
                                    cacheList.Collection.Remove(last);
                                }
                            }
                        }
                    }
                }

                if (cacheList.AddCheck == null || cacheList.AddCheck(loggingEvent))
                {
                    if (cacheList.CollectionOwner.InvokeRequired)
                    {
                        cacheList.CollectionOwner.Invoke(new System.Threading.ThreadStart(delegate()
                        {
                            cacheList.Collection.Insert(0, loggingEvent);
                        }));
                    }
                    else
                    {
                        cacheList.Collection.Insert(0, loggingEvent);
                    }
                }
            }

        }

        public void AddCacheCollection(BindingList<LoggingEvent> bindCollection, uint bindMaxCount, Form bindOwner, Func<LoggingEvent, bool> bindCheck)
        {
            if (bindCollection == null)
                throw new ArgumentNullException("bindCollection", "need bindCollection");
            if (bindMaxCount < 1)
                throw new ArgumentException("bindMaxCount 至少大于0", "bindMaxCount");
            if (bindOwner == null)
                throw new ArgumentNullException("bindOwner", "need bindOwner");

            if (bindCacheList.Any(bl => bl.Collection.Equals(bindCollection)))
                return;
            bindCacheList.Add(new LogCacheCollection(bindCollection, bindMaxCount, bindOwner, bindCheck));
        }

    }
}
